

#ifndef SERIALMEMORYMANAGER_H_
#define SERIALMEMORYMANAGER_H_


#include <boost/unordered_map.hpp>
#include <algorithm>
#include <vector>
#include <set>
#include "../Common/Consts.h"
#include "Components/Encoder.h"
#include "Components/Collector.h"
#include "Memory Tables/MemoryTable.h"
#include "../Packets/BackSubPkt.h"
#include "../Packets/PubPkt.h"
#include <iostream>
#include "../Util/Util.h"
#include "../Common/Timer.h"


using namespace std;


class SerialMemoryManager : public MemoryManager {

public:
	/**
	 * Creates the Memory Manager
	 */
	SerialMemoryManager(MemoryTable *parMemoryTable, int subscriptionThreshold, int parNumClusters, float parLastThreshold);

	virtual ~SerialMemoryManager();

	void addEvent(PubPkt *pkg);

	void addSubscription(BackSubPkt *pkg);

	void queryEventSet(BackSubPkt *pkg, Outbox &outbox);

	/**
	 *  the thread to update the table of informations for the storage
	 */
	void updateTable();

private:


	pthread_t *updatingThread;						// Thread managing the memory table

	Collector *collector;
	Encoder *encoder;

	typedef struct SubscribtionInfoStruct {
		vector<float> windowsList;
		int countLast;
	} SubscribtionInfo;

	boost::unordered_map<string, SubscribtionInfo> subscriptionMap;
	boost::unordered_map<string, int> eventMap;

	pthread_mutex_t *subscriptionMapMutex;
	pthread_mutex_t *eventMapMutex;

	MemoryTable *memoryTable;
	pthread_mutex_t *memoryTableMutex;

	int collectorThreshold;
	float lastThreshold;
	bool memoryTableToReset;
	pthread_mutex_t *memoryTableToResetMutex;

	int updatingCounter;
	int updatingThreshold;

	//Timer *timer;
};

namespace serial_manager {


void * startUpdatingThread(void *input);

}

#endif /* SERIALMEMORYMANAGER_H_ */
